package cn.jingyuan.swan.cloud.oauth2;

import cn.jingyuan.bee.utils.bean.BeanUtils;
import cn.jingyuan.bee.utils.map.MapUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import static org.springframework.security.oauth2.provider.token.UserAuthenticationConverter.AUTHORITIES;
import static org.springframework.security.oauth2.provider.token.UserAuthenticationConverter.USERNAME;


public class AuthenticationPrincipalHelper {

    /**
     * 抽取用户详情
     */
    public static DefaultUserDetails extractUserDetails(Map<String, ?> map) {
        Map<String, Object> params = new HashMap<>(16);
        for (String key : map.keySet()) {
            if (USERNAME.equals(key)) {
                if (map.get(key) instanceof Map) {
                    params.putAll((Map) map.get(key));
                } else if (map.get(key) instanceof DefaultUserDetails) {
                    return (DefaultUserDetails) map.get(key);
                } else {
                    params.put(key, map.get(key));
                }
            } else {
                params.put(key, map.get(key));
            }
        }

        DefaultUserDetails userDetails = BeanUtils.mapToBean(params, DefaultUserDetails.class, false);
        if (params.get(USERNAME) != null) {
            userDetails.setUsername(params.get(USERNAME).toString());
        }

        // 未使用
        // if (params.get(DefaultSecurityConstants.OPEN_ID) != null) {
        //     userDetails.setUserId(Long.parseLong(params.get(DefaultSecurityConstants.OPEN_ID).toString()));
        // }

        // 未使用
        // if (params.get(OpenSecurityConstants.DOMAIN) != null) {
        //     userDetails.setDomain(params.get(OpenSecurityConstants.DOMAIN).toString());
        // }

        Object clientId = params.get(AccessTokenConverter.CLIENT_ID);
        if (null != clientId) {
            userDetails.setClientId(clientId.toString());
        }

        userDetails.setAuthorities(AuthenticationPrincipalHelper.extractAuthorities(map));
        return userDetails;
    }

    /**
     * 抽取权限
     *
     * @param map
     *
     * @return {@link Collection<GrantedAuthority> grantedAuthorities} 权限信息
     */
    public static Collection<? extends GrantedAuthority> extractAuthorities(Map<String, ?> map) {
        if (MapUtils.notContainsKey(map, AUTHORITIES)) {
            return AuthorityUtils.NO_AUTHORITIES;
        }

        Object authorities = map.get(AUTHORITIES);
        if (authorities instanceof String) {
            return AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities);
        }
        if (authorities instanceof Collection) {
            return AuthorityUtils.commaSeparatedStringToAuthorityList(
                StringUtils.collectionToCommaDelimitedString((Collection<?>) authorities)
            );
        }

        throw new IllegalArgumentException("authorities must be either a string or a collection");
    }

}
